/** @format */
import { resultsModel } from '../../sdk'
import { CODE_TYPES } from '../../constants'
import { logFn, recordErrorLog } from '../../utils'
import { cloundAlarm } from '../../utils/common/dingTalk'

/**
 *  限制单位时间接口请求次数
 *
 * @export
 * @param {number} limitCount 限制次数
 * @param {number} limitTime 限制的单位时间
 * @return {*}
 */
export default function requestCountLimit(limitCount: number, limitTime: number) {
  return function (target: Object, name: string, descriptor: PropertyDescriptor) {
    const method = descriptor.value

    descriptor.value = async function (...args: any[]) {
      const recordTableName = 'c_test'
      const [context, baseInfos = {}, services = [], preCheckData = {}] = args
      const { activityId } = context.data
      const { openId } = context
      const handler = context?.cloud?.dataspace?.context?.handler
      const now = Date.now()
      try {
        const data = await context.cloud.dataspace.executeSql(
          `SELECT gmt_modified, expired_time, count FROM ${recordTableName} where activity_id = ? and open_id = ? and handler = ?`,
          [activityId, openId, handler]
        )

        const handlerRecord = data?.[0]

        if (!handlerRecord) {
          context.cloud.dataspace.executeSql(
            `insert into ${recordTableName}(activity_id,open_id,handler,count, expired_time) values(?,?)`,
            [activityId, openId, handler, 1, now + limitTime]
          )
        } else {
          if (now <= handlerRecord.expired_time) {
            if (handlerRecord?.count < limitCount) {
              await context.cloud.dataspace.executeSql(
                `update ${recordTableName} set count = ? where activity_id = ? and open_id = ? and handler = ?`,
                [handlerRecord?.count + 1, activityId, openId, handler]
              )
            } else {
              return resultsModel.error(CODE_TYPES.SYSTEM_ERROR, '请求过于频繁，请稍后再试~')
            }
          }
          if (now > handlerRecord.expired_time) {
            await context.cloud.dataspace.executeSql(
              `update ${recordTableName} set count = ? expired_time = ? where activity_id = ? and open_id = ? and handler = ?`,
              [1, now + limitTime, activityId, openId, handler]
            )
          }
        }
      } catch (error) {
        console.log('error', error)
        recordErrorLog(context, baseInfos, error.toString(), error.stack)
        // 云告警
        cloundAlarm(context, error.toString())
        return resultsModel.error(CODE_TYPES.SYSTEM_ERROR)
      }

      return method.apply(target, [context, baseInfos, services, preCheckData])
    }
  }
}
